//
//  TorchManage.m
//  Flashlight
//
//  Created by Eric on 4/14/13.
//  Copyright (c) 2013 Saick. All rights reserved.
//

#import "TorchManage.h"
#import "SQLibs.h"
#import "global_Header.h"
#import "TorchConfig.h"
#import "WhiteTorchViewController.h"

@implementation TorchManage

static TorchManage* defaultManager;

- (void)dealloc
{
    NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
    [notifCenter removeObserver:self];
    
    [_sound release];
    [_wWhite release];
    [_vcWhiteTorch release];
    
    [super dealloc];
}

+ (TorchManage *)defaultManager
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        defaultManager = [[self alloc] init];
    });
    
    return defaultManager;
}

- (id)init
{
    if (self = [super init]) {
        _sound = [[SQSoundManager alloc] init];
        
        NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
        [notifCenter addObserver:self
                        selector:@selector(applicationDidEnterBackground:)
                            name:UIApplicationDidEnterBackgroundNotification
                          object:nil];
        [notifCenter addObserver:self
                        selector:@selector(applicationDidBecomeActive:)
                            name:UIApplicationDidBecomeActiveNotification
                          object:nil];
        
        [notifCenter addObserver:self
                        selector:@selector(batteryLevelDidChange)
                            name:UIDeviceBatteryLevelDidChangeNotification
                          object:nil];
        [notifCenter addObserver:self
                        selector:@selector(batteryStateDidChange)
                            name:UIDeviceBatteryStateDidChangeNotification
                          object:nil];
        
        // about battery
        UIDevice *device = [UIDevice currentDevice];
        device.batteryMonitoringEnabled = YES;  // for both notification and the api's access to get battery info
    }
    return self;
}

#pragma mark - battery notif

- (void)batteryLevelDidChange
{
    SQTRACE(@"batteryLevelDidChange");
    
    if ([TorchConfig sharedConfig].fStopTorch >= [UIDevice currentDevice].batteryLevel) {
        AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if (captureDevice.hasTorch) {
            if (captureDevice.torchMode == AVCaptureTorchModeOn) {
                [self showWhite:_fTorchLevel];
            }
        } // hasTorch
    }
    
    if ([TorchConfig sharedConfig].isSavingAutomatic) {
        AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if (captureDevice.hasTorch) {
            if (captureDevice.torchMode == AVCaptureTorchModeOn) {
                BOOL locked = NO;
                do {
                    locked = [captureDevice lockForConfiguration:nil];
                } while (!locked);
                
                if (locked) {
                    if (kOSVersion >= 6.0f) {
                        CGFloat fLevel = [UIDevice currentDevice].batteryLevel * 0.7f;
                        [captureDevice setTorchModeOnWithLevel:fLevel error:nil];
                    }
                    [captureDevice unlockForConfiguration];
                }
            }
        } else { // hasTorch
            if (_wWhite.hidden == NO) {
                CGFloat fLevel = [UIDevice currentDevice].batteryLevel * 0.7f;
                _vcWhiteTorch.vMask.alpha = (1.0f - fLevel) * 0.7f;
            }
        }
    }
    
    [MobClick event:@"batteryLevelDidChange" label:[NSString stringWithFormat:@"%.2f", [UIDevice currentDevice].batteryLevel]];
}

- (void)batteryStateDidChange
{
    SQTRACE(@"batteryStateDidChange");
    
    // test
    UIDevice *device = [UIDevice currentDevice];
    if (device.batteryState == UIDeviceBatteryStateUnknown) {
        NSLog(@"UnKnow");
    } else if (device.batteryState == UIDeviceBatteryStateUnplugged) {
        NSLog(@"Unplugged");
    } else if (device.batteryState == UIDeviceBatteryStateCharging) {
        NSLog(@"Charging");
    } else if (device.batteryState == UIDeviceBatteryStateFull) {
        NSLog(@"Full");
    }
    NSLog(@"%f", device.batteryLevel);
    
    [MobClick event:@"batteryStateDidChange" label:[NSString stringWithFormat:@"%d", [UIDevice currentDevice].batteryState]];
}

#pragma mark - application notif

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    
    [MobClick endEvent:@"LightOnLastTime" label:@"applicationDidEnterBackground"];
    [MobClick endEvent:@"WhiteOnLastTime" label:@"applicationDidEnterBackground"];
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    if (_fTorchLevel == 0.0f)
        return;
    
    [self showTorch:_fTorchLevel];
}

#pragma mark - torch

- (void)showTorch:(float)fLevel
{
    [MobClick event:@"ShowTorch" label:[NSString stringWithFormat:@"%.2f", fLevel]];
    
    if ([TorchConfig sharedConfig].isSavingAutomatic) {
        _fTorchLevel = fLevel * [UIDevice currentDevice].batteryLevel;
    } else {
        _fTorchLevel = fLevel;
    }
    
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotifUpdateLCD
                                                        object:nil
                                                      userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:_fTorchLevel] forKey:@"level"]];
    
    [_sound playCafFile:[[NSBundle mainBundle] pathForResource:@"cell_move" ofType:@"wav"] volume:1.f];
    
    AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;
    
    if ([captureDevice hasTorch]) {
        if ([TorchConfig sharedConfig].fStopTorch >= [UIDevice currentDevice].batteryLevel) {
            [self showWhite:fLevel];
            
            return;
        }
        
        BOOL locked = NO;
        do {
            locked = [captureDevice lockForConfiguration:&error];
        } while (!locked);
        
        if (locked) {
            if (fLevel <= 0.0f) {
                captureDevice.torchMode = AVCaptureTorchModeOff;
                [MobClick endEvent:@"LightOnLastTime"];
            } else {
                if (kOSVersion >= 6.0f)
                    [captureDevice setTorchModeOnWithLevel:fLevel error:nil];
                captureDevice.torchMode = AVCaptureTorchModeOn;
                
                [[NSNotificationCenter defaultCenter] postNotificationName:kNotifMoveOnMainScrollPosition object:nil];
                [MobClick beginEvent:@"LightOnLastTime"];
            }
            [captureDevice unlockForConfiguration];
        }
    } else {
        [self showWhite:fLevel];
    }
}

- (void)showWhite:(CGFloat)fLevel
{
    [MobClick event:@"ShowWhite" label:[NSString stringWithFormat:@"%.2f", fLevel]];
    
    if (_wWhite == nil) {
        _wWhite = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        _wWhite.windowLevel = UIWindowLevelNormal + 1;
        _wWhite.backgroundColor = [UIColor clearColor];
        _wWhite.userInteractionEnabled = YES;
    }
    
    if (_vcWhiteTorch == nil)
        _vcWhiteTorch = [[WhiteTorchViewController alloc] init];
    
    if (fLevel <= 0.0f) {
        _wWhite.hidden = YES;
        [[NSNotificationCenter defaultCenter] postNotificationName:kNotifRestoreMainScrollPosition object:nil];
        
        [MobClick endEvent:@"WhiteOnLastTime"];
    } else {
        _wWhite.hidden = NO;
        
        _vcWhiteTorch.view.frame = _wWhite.bounds;
        _vcWhiteTorch.vMask.alpha = (1.0f - fLevel) * 0.7f;
        
        [_wWhite addSubview:_vcWhiteTorch.view];
        
        [MobClick beginEvent:@"WhiteOnLastTime"];
    }
}

@end
